/*
**NCS signal module have files sig.c
**This module provide signal processing APIs for NCS 
**NCS uses signal frame to communicate with other devs
**including RXEMS RCST SIGEMS PP
**
**Copyright (C) 2016-xxxx andisat <www.andisat.com>
**
**Author: andisat
**Date:2016-1
**
*/
/**
**  The Frame is following structure:
      |ver(1) |srcType(1)|  Msg(2)   |   Seq(4)   |  srcDevId(4)  | Len(2)  |  TLV(N)   |
      I.   The MAX frame len is 1500 bytes.
      II.  The frame byte-order is network order
      III. If NCS receive the reponse signal,NCS do not need to retransmit packet
**/

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h> 
#include <stdlib.h>
#include <arpa/inet.h>
#include "ncs_list.h"
#include "ncs_log.h"
#include "ncs_network.h"
#include "ncs_fsm.h"
#include "ncs_cfg.h"
#include "ncs_dev.h"
#include "ncs_serv.h"
#include "ncs_msg.h"
#include "ncs_serv.h"
#include "ncs_sig.h"
#include "ncs_resmng.h"
#include "event.h"


int get_seq(int *seq)
{
    if(!seq)
        return 0;

    if(0XFFFFFFFF == *seq){
        *seq=1;
        return 0;
    }
    else{
        *seq += 1;
        return (*seq-1);
    }
}

void packet_free(void *packet)
{
    if(packet)
        free(packet);

    return;
}

int packet_compare_by_seq(void *val1,void *val2)
{
    int seq;
    struct packet_ctl *packetctl;
    
    if(!val1 || !val2)
        return -1;

    seq = *((int *)val1);
    packetctl = (struct packet_ctl *)val2;

    if(seq == packetctl->seq)
        return 0;
    else if(seq < packetctl->seq)
        return -1;
    else
        return 1;
}

char *build_tlv(struct tlv_hdr *ptlv,char type,void *val,short len)
{
    char *paddr = (char *)ptlv;
    
    if(!ptlv || !val)
        return NULL;
    
    ptlv->type=type;
    ptlv->len=htons(len);
    
    memcpy((void *)(ptlv+1),val,len);

    return (char *)(paddr+TLV_HEAD_LEN+len);
}

struct packet_ctl *build_packet_ctl(int size)
{
    int len;
    struct packet_ctl *ptr=NULL;

    len=size+sizeof(struct packet_ctl);
    if(ptr=(struct packet_ctl *)malloc(len))
        memset(ptr,0,len);

    return ptr;
}

void del_packetctl(struct list *out,struct packet_ctl *pctl)
{
    if(pctl)
        listnode_delete(out, (void *)&(pctl->seq));

    return;   
}

struct packet_ctl *find_packetctl(struct list *out,int seq)
{    
    struct packet_ctl *packetctl=NULL;
    listnode node=NULL;
    
    if(out)
         if(node=listnode_lookup(out,(void *)&seq))
            packetctl=(struct packet_ctl *)(node->data);
         
    return packetctl;
}


struct packet_hdr *build_packet(int size)
{
    struct packet_hdr *phdr=NULL;
    
     if(phdr=(struct packet_hdr *)malloc(PACKET_HEAD_LEN+size))
    {
        memset(phdr,0,(PACKET_HEAD_LEN+size));
        phdr->ver = NCS_VERSION;
        phdr->len = htonl(size);
     }

    return phdr;
}

void add_packetctl(struct list* out,
    struct packet_ctl *pctl)
{
    if(out && pctl)
        listnode_add(out, (void *)pctl);
    return;
}

void ncs_free_packetctl_list(struct dev_obj *dev)
{
    if(dev && dev->out)
        list_delete_all_node (dev->out);
    return;
}

struct packet_ctl * ncs_add_packetctl_list(struct dev_obj *dev,char *packet,int len)
{
    char *ptr;
    struct packet_hdr *packethdr;
    struct packet_ctl *packetctl;
    
    if(!packet || !dev)
        return NULL;

    if(packetctl=build_packet_ctl(len))
    {
        ptr=(char *)(packetctl + 1);
        memcpy(ptr,packet,len);

        packethdr=(struct packet_hdr *)ptr;
        packetctl->msg = ntohl(packethdr->msg);
        packetctl->seq = ntohl(packethdr->seq);
        packetctl->tries = 1;
        packetctl->dip = dev->ip;
        packetctl->dport = dev->port;
        packetctl->type = dev->type;
        packetctl->devId = dev->devId;
        packetctl->len = len;
        
        add_packetctl(dev->out,packetctl);           
    }
    
    return packetctl;
}

int modem_auth_check(struct dev_obj *dev,
    struct _STR_MODEM_ *pmodem,
    struct _STR_LICENSE_INFO_ *plicense)
{
    if(!dev || !pmodem || !plicense)
        return FAILURE;

    if((dev->devId != ntohl(pmodem->devId))
        || memcmp(dev->devSN,pmodem->devSN,9)
        || dev->ip != ntohl(pmodem->ip))
        return FAILURE;

    /*To do: check the dev's ability*/
    #if 0
    if(!ncs_get_dev_ability())
        return FAILURE;
    #endif
    
    return SUCCESS;
}

int ncs_send_packet(int fd,int dip,short dport,
    char *buf,int len)
{
    int ret;
    struct sockaddr_in addr;
    
    if(!buf || !len)
        return -1;

    addr.sin_family=AF_INET;
    addr.sin_port=htons(dport);
    addr.sin_addr.s_addr=htonl(dip);

    ret=sendto(fd,buf,len,0,(struct sockaddr *)&addr,sizeof(struct sockaddr));
    if(-1 == ret)
    {
        ncs_log(ERR,"%s ncs send packet failure,%s",__func__,strerror(errno));
        return -1;
    }
    else if(ret != len)
    {
        ncs_log(ERR,"NCS send packet %d bytes",
            __func__,ret);
        return -1;
    }
    
    return 0;
}
void ncs_send_broadcast(evutil_socket_t fd, 
    short event, void *ptr)
{
    struct packet_ctl *packetctl;
    
    if((NULL == ptr) || 
        (ONLINE != g_ncs_base.state))
    {
        if(ptr)
            free(ptr);

        event_del(g_ncs_base.send_broadcast_timerev);
        g_ncs_base.send_broadcast_timerev=NULL;
    }
    
    packetctl=(struct packet_ctl *)ptr;
    
    ncs_log(INFO,"%s len:%d ip:%d port:%d",__func__,
        packetctl->len,packetctl->dip,packetctl->dport);
    
    ncs_send_packet(g_ncs_base.servd_fd,
                               packetctl->dip,
                               packetctl->dport,
                               (char *)(packetctl+1),
                               packetctl->len);

    return;
    
}

int ncs_start_broadcast(struct ncs_object *ncs)
{
    int len;
    struct tlv_hdr *ptlv;
    struct timeval timeout;
    struct packet_hdr *packet;
    struct packet_ctl *packetctl;
    struct _STR_IPPORT_ *pipport;
    
    if(!ncs || (ONLINE != ncs->state))
        return -1;

    /*set socket broadcast attribute*/
    int so_broadcast=1;
    setsockopt(ncs->servd_fd,SOL_SOCKET,SO_BROADCAST,&so_broadcast,sizeof(so_broadcast));
    
    /*Multicast packet length*/
    len=TLV_HEAD_LEN+sizeof(struct _STR_IPPORT_);
    if(!(packetctl = build_packet_ctl(len+PACKET_HEAD_LEN))){
        ncs_log(ERR,"%s build packet failure",__func__);
        return -1;
    }
    
    packetctl->dport=BROADCAST_UDP_PORT;         /*To do: add broadcast sending port*/
    packetctl->msg=__NCS_BROADCAST_IPPORT__;
    packetctl->seq=rand();
    packetctl->dip=0XFFFFFFFF;
    packetctl->len = len;
    
    packet=(struct packet_hdr *)(packetctl+1);
    packet->msg=htons(packetctl->msg);
    packet->srcType=DEV_TYPE_NCS;
    packet->srcDevId=htonl(ncs->devId);
    packet->seq=packetctl->seq;
    packet->len=htons(len);
    
    ptlv = (struct tlv_hdr *)(packet +1);
    ptlv->type = _IPPORT_;
    ptlv->len = htons(sizeof(struct _STR_IPPORT_));

    pipport=(struct _STR_IPPORT_ *)(ptlv+1);
    pipport->ip = htonl(ncs->servd_ip); 
    pipport->port = htons(ncs->servd_port);

    ncs->send_broadcast_timerev=event_new(ncs->g_base,ncs->servd_fd,
        (EV_TIMEOUT|EV_PERSIST),ncs_send_broadcast,packetctl);
    if(ncs->send_broadcast_timerev==NULL){
        ncs_log(ERR,"%s create the event of sending broadcast timer event failure",__func__);
        return -1;
    }

    timeout.tv_usec = 0;
    timeout.tv_sec = ncs->g_retransmit_timeout;
    event_add(ncs->send_broadcast_timerev,&timeout);
    
    return 0;       
}


void ncs_start_dev_poll_event(struct ncs_object *ncs,struct dev_obj *dev)
{
    struct dev_set *devset;
    struct timeval timeout;

    if(!ncs || !dev)
        return;

    if(dev->type==DEV_TYPE_PP)
        devset=ncs->pp_set;
    else if(dev->type==DEV_TYPE_SIGEMS)
        devset=ncs->sig_set;
    else if(dev->type==DEV_TYPE_RXEMS)
        devset=ncs->rx_set;
    else if(dev->type==DEV_TYPE_RCST)
        devset=ncs->rcst_set;
    else
        return;
    
    timeout.tv_usec = 0;
    timeout.tv_sec = ncs->g_retransmit_timeout;
    /*start poll timer event*/
    if(!devset->poll_timerev)
        devset->poll_timerev = event_new(ncs->g_base,ncs->servd_fd,
            (EV_TIMEOUT|EV_PERSIST),devset->poll,ncs);
    if(!devset->poll_timerev)
        ncs_log(ERR,"%s add dev(type:%d Id:%d) poll timer event failure",
            __func__,dev->type,dev->devId);
    else
        event_add(devset->poll_timerev,&timeout);

    return;
}

void ncs_start_send_Ib_event(struct ncs_object *ncs,struct dev_obj *dev)
{
    struct timeval timeout;

    timeout.tv_usec = 0;
    timeout.tv_sec = ncs->g_retransmit_timeout;

    if(ncs->send_ib_timerev)
        ncs->send_ib_timerev = event_new(ncs->g_base,ncs->servd_fd,
            (EV_TIMEOUT|EV_PERSIST),ncs2sig_send_IB,(void *)ncs);
    
    if(!ncs->send_ib_timerev)
        ncs_log(ERR,"%s add sending Ib-Information event failure",__func__);
    else
        event_add(ncs->send_ib_timerev,&timeout);

    return;
}

int ncs2dev_send_cfg(struct ncs_object *ncs,
        struct dev_obj *dev,char *pinfo,int len)
{
    int ret;
    struct packet_hdr *packethdr;
    
    if(!ncs || !dev || !pinfo)
        return -1;
    
    if(NULL == (packethdr=build_packet(len)))
        return -1;

    packethdr->srcType = DEV_TYPE_NCS;
    packethdr->srcDevId = htonl(ncs->devId);
    packethdr->seq = htonl(get_seq(&(dev->s_seq)));
    packethdr->len=htonl(len);
    
    if(dev->type==DEV_TYPE_PP)
        packethdr->msg=htons(__NCS2PP_PARCFG_UPDATE_REQ__);
    else if(dev->type==DEV_TYPE_SIGEMS)
        packethdr->msg=htons(__NCS2SIG_PARCFG_UPDATE_REQ__);
    else if(dev->type==DEV_TYPE_RXEMS)
        packethdr->msg=htons(__NCS2RX_PARCFG_UPDATE_REQ__);
    else if(dev->type==DEV_TYPE_RCST)
        packethdr->msg=htons(__NCS2RCST_PARCFG_UPDATE_REQ__);
    else
        ;
    
    memcpy((packethdr+1),pinfo,len);
        
    ret=ncs_send_packet(ncs->servd_fd, dev->ip, dev->port, 
        (char *)packethdr, len+PACKET_HEAD_LEN);
    if(ret == 0){
        struct packet_ctl *packetctl;
        packetctl=ncs_add_packetctl_list(dev,(char *)packethdr,(len+PACKET_HEAD_LEN));
        add_retransmit_timer(ncs,packetctl);
    }
    else
        ncs_log(ERR,"%s ncs send update configures failure",__func__);

    free(packethdr);
    return 0;
}

void ncs2sig_send_IB(evutil_socket_t fd,short event,void *arg)
{
    int bytes=0;
    char *pbuff;
    struct ncs_object *ncs;
    struct packet_hdr *packet;
    struct dev_obj *sig;
    struct dev_set *sigset;
    
    if(!arg)
        return;
    
    ncs=(struct ncs_object *)arg;
    sigset=ncs->sig_set;
    
    if(sigset->count <= 0 || !(sig=ncs_get_active_sig(ncs)))
        goto DEL_EVENT;
    
    packet=build_packet(PACKET_PDU_MAX);
    packet->srcType=DEV_TYPE_NCS;
    packet->srcDevId=htonl(ncs->devId);
    packet->seq=htonl(get_seq(&(sig->s_seq)));
    packet->msg=htons(__NCS_SEND_IB_INFO__);
    
    pbuff=(char *)(packet+1);
    /*Add carrier to packet*/
    struct _STR_CARRIER_ ib;
    get_cfg_dev_ib(&ib);
    bytes += packet_add_carrier_tlv(pbuff,&ib,sizeof(ib));
    
    /*Add default gateway to packet*/
    struct _STR_DEFAULT_GWIP_ gwip;
    gwip.gateway=sig->ip;
    bytes += packet_add_gwip_tlv((pbuff+bytes),&gwip,sizeof(gwip));
    
    packet->len=htonl(bytes);
    ncs_send_packet(ncs->servd_fd, sig->ip, sig->port, (char *)packet, (bytes+PACKET_HEAD_LEN));

    free(packet);

DEL_EVENT:
    if(ncs->send_ib_timerev)
    {
        event_del(ncs->send_ib_timerev);
        ncs->send_ib_timerev=NULL;
    }
    
    return;
}

void ncs_del_packet_from_list(struct packet_ctl *packetctl)
{
    struct dev_obj *dev;
    struct ncs_object *ncs=&g_ncs_base;
    
    if(!packetctl)
        return;

    if(packetctl->type==DEV_TYPE_RCST)
        dev=ncs_find_rcst(ncs,packetctl->devId);
    else if(packetctl->type==DEV_TYPE_RXEMS)
        dev=ncs_find_rx(ncs,packetctl->devId);
    else if(packetctl->type==DEV_TYPE_SIGEMS)
        dev=ncs_find_sig(ncs,packetctl->devId);
    else if(packetctl->type==DEV_TYPE_PP)
        dev=ncs_find_sig(ncs,packetctl->devId);

    del_packetctl(dev->out,packetctl);

    return;
}

void ncs_resend_packet(evutil_socket_t fd, 
    short event, void *ptr)
{
    struct packet_ctl *packetctl;
    struct packet_hdr *packet;
    
    if(!ptr || !(event & EV_TIMEOUT) )
        return;

    packetctl=(struct packet_ctl *)ptr;

    /*If the tries >= max && not receive ack, then cancel
       this timer,drop this packet and report to NMS*/
    if(packetctl->tries >= g_ncs_base.g_retransmit_max)
    {
        ncs_log(WARN,"%s the times of retransmitting packet reach max",__func__);
        
        ncs_proc_resend_max(packetctl);
        ncs_del_packet_from_list(packetctl);        
        event_del(packetctl->retry_timerev);
        free(packetctl);
        return;
    }
    
    /*If ncs need to retransmit packet,get the packet to resend*/
    packet = (struct packet_hdr *)(packetctl+1);
    if(0 != ncs_send_packet(fd,packetctl->dip, 
        packetctl->dport,(char *)packet, packetctl->len))
    {
        ncs_log(ERR,"%s Ncs retransmit packet msg(%d) failure",
            __func__,packetctl->msg);
        
        ncs_del_packet_from_list(packetctl);
        event_del(packetctl->retry_timerev);
        free(packetctl);
        return;
    }
    else
        packetctl->tries += 1;
    
    return;
}

void ncs2rcst_resend_max(struct packet_ctl *packetctl)
{
    int event;
    struct dev_obj *rcst;
    struct _STR_CHANNEL_ID_ rcstcha;
    
    if(!packetctl)
        return;

    if(packetctl->msg == __NCS2RCST_LOGOFF_REQ__)
        event=RECEIVE_RCST_LOGOFF_ACK;
    else if(packetctl->msg == __NCS2RCST_RELEASE_RESOURCE_REQ__)
        event=RECEIVE_RCST_RELRES_ACK;
    else if(packetctl->msg == __NCS2RCST_CARRIERLOCK_RELEASE_REQ__)
        event=RECEIVE_RCST_LOCKREL_ACK;
    else
        return;

    rcstcha.devId=packetctl->devId;
    rcstcha.chaId=PATH_FIRST;
    if(!ncs_relres_by_rcst(&rcstcha))
        ncs_log(ERR,"%s release rcst(Id:%d) resource failure",__func__,rcstcha.devId);

    if(rcst=ncs_find_rcst(&g_ncs_base,packetctl->devId))
        rcst_fsm_change(rcst,event);

    return;
}

void ncs2rx_resend_max(struct packet_ctl *packetctl)
{
    int event,rxchanum;
    FSM_CALLFUNC func;
    struct packet_hdr *packet;
    struct dev_obj *rcst,*rx=NULL;
    struct _STR_CHANNEL_ID_ newrxchaId;
    struct _STR_CHANNEL_ID_ *prxchaId;
    struct _STR_CHANNEL_ID_ txchaId;
    
    if(!packetctl)
        return;

    ncs_log(WARN,"%s the tims of packet(msg:%d) reach to the MAX",__func__,packetctl->msg);
    
    if(packetctl->msg == __NCS2RX_OPENRXCHA_REQ__)
    {            
        packet=(struct packet_hdr *)(packetctl+1);
        prxchaId=(struct _STR_CHANNEL_ID_ *)((char *)(packet+1)+TLV_HEAD_LEN);
        prxchaId->devId=ntohl(prxchaId->devId);
    
        if(ncs_getrcst_by_rx(prxchaId,&txchaId) && (rcst=ncs_find_rcst(&g_ncs_base,txchaId.devId)))
        {                      
            if(ncs_reallocres_by_rcst(&txchaId,&newrxchaId,NULL))
            {
                rxchanum=newrxchaId.chaId;
                event=RCST_RESALLOC_SUCCESS;
                rx=ncs_find_rx(&g_ncs_base,newrxchaId.devId);
            }
            else
                event=RCST_RESALLOC_FAILURE;
     
            if(func=RCST_FSM[rcst->state][event].func)
                if(-1 != func(&g_ncs_base,rcst,rx,rxchanum))
                    rcst_fsm_change(rcst,event);
        }
    }

    return;
}

void ncs2sig_resend_max(struct packet_ctl *packetctl)
{
    ncs_log(WARN,"%s the tims of packet(msg:%d) reach to the MAX",__func__,packetctl->msg);
    return;
}

void ncs2pp_resend_max(struct packet_ctl *packetctl)
{
    ncs_log(WARN,"%s the tims of packet(msg:%d) reach to the MAX",__func__,packetctl->msg);
    return;
}

void ncs_proc_resend_max(struct packet_ctl *packetctl)
{
    if(packetctl)
        return;

    ncs_log(WARN,"%s the tims of packet(msg:%d) reach to the MAX",__func__,packetctl->msg);
    
    if(packetctl->type==DEV_TYPE_RCST)
        ncs2rcst_resend_max(packetctl);
    else if(packetctl->type==DEV_TYPE_RXEMS)
        ncs2rx_resend_max(packetctl);
    else if(packetctl->type==DEV_TYPE_SIGEMS)
        ncs2sig_resend_max(packetctl);
    else if(packetctl->type==DEV_TYPE_PP)
        ncs2pp_resend_max(packetctl);
    else
        ncs_log(ERR,"%s can't process the dev type(%d)",
            __func__,packetctl->type);

    return;
}

int add_retransmit_timer(struct ncs_object *ncs,
    struct packet_ctl *packet)
{
    struct timeval timeout;

    if(!ncs || !packet)
        return -1;

    packet->retry_timerev = event_new(ncs->g_base,ncs->servd_fd,
                        (EV_TIMEOUT|EV_PERSIST), ncs_resend_packet, packet);
    if(!packet->retry_timerev)
    {
        ncs_log(ERR,"%s add retransmit packet msg(%d) failure",__func__,packet->msg);
        free(packet);
        return -1;
    }

    timeout.tv_sec = ncs->g_retransmit_timeout;
    timeout.tv_usec = 0;
    event_add(packet->retry_timerev, &timeout);

    return 0;    
}

int packet_add_resourcerule_tlv(char *pinfo,
        struct _STR_RESOURCE_RULE_ITEMS_ *presourcerule,int len)
{
    struct tlv_hdr *ptlv;

    if(!pinfo || !presourcerule)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_RESOURCE_RULE_ITEMS_;
    ptlv->len=htons(len);
    
    memcpy((ptlv+1),presourcerule,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_add_resourcebod_tlv(char *pinfo,
        struct _STR_RESOURCE_BOD_ *presourcebod,int len)
{
    struct tlv_hdr *ptlv;
    struct _STR_RESOURCE_BOD_ resourcebod;

    if(!pinfo || !presourcebod)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_RESOURCE_BOD_;
    ptlv->len=htons(len);

    resourcebod.initBW=htonl(presourcebod->initBW);
    resourcebod.step=htonl(presourcebod->step);
    resourcebod.maxStep=presourcebod->maxStep;
    resourcebod.enable=presourcebod->enable;
    
    memcpy((ptlv+1),&resourcebod,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_add_resource_tlv(char *pinfo,
        struct _STR_RESOURCE_ *presource,int len)
{
    struct tlv_hdr *ptlv;
    struct _STR_RESOURCE_ resource;

    if(!pinfo || !presource)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_RESOURCE_;
    ptlv->len=htons(len);

    resource.freq=htonl(presource->freq);
    resource.BW=htonl(presource->BW);
    
    memcpy((ptlv+1),&resource,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_add_workmode_tlv(char *pinfo,
        struct _STR_WORK_MODE_ *pworkmode,int len)
{
    struct tlv_hdr *ptlv;
    struct _STR_WORK_MODE_ workmode;
    
    if(!pinfo || !pworkmode)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_WORK_MODE_;
    ptlv->len=htons(len);

    workmode.workMod=pworkmode->workMod;
    workmode.resMod=pworkmode->resMod;
    workmode.qosMod=pworkmode->qosMod;
    workmode.closeTime=htonl(pworkmode->closeTime);
    
    memcpy((ptlv+1),&workmode,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_add_chaId_tlv(char *pinfo,
        struct _STR_CHANNEL_ID_ *pchaId,int len)
{
    struct tlv_hdr *ptlv;
    struct _STR_CHANNEL_ID_ chaId;
    
    if(!pinfo || !pchaId)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_CHANNEL_ID_;
    ptlv->len=htons(len);

    chaId.devId=htonl(pchaId->devId);
    chaId.chaId=pchaId->chaId;
    memcpy((ptlv+1),&chaId,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_add_devtime_tlv(char *pinfo,
        struct _STR_DEV_TIME_ *pdevtime,int len)
{
    struct tlv_hdr *ptlv;
    struct _STR_DEV_TIME_ devtime;

    if(!pinfo || !pdevtime)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_DEV_TIME_;
    ptlv->len=htons(len);
    devtime.time=htonl(pdevtime->time);
    memcpy((ptlv+1),&devtime,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_add_devname_tlv(char *pinfo,
        struct _STR_DEV_NAME_ *pdevname,int len)
{
    struct tlv_hdr *ptlv;

    if(!pinfo || !pdevname)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_DEV_NAME_;
    ptlv->len=htons(len);

    memcpy((ptlv+1),pdevname,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_add_carrier_tlv(char *pinfo,
        struct _STR_CARRIER_ *pcarrier,int len)
{
    struct tlv_hdr *ptlv;
    struct _STR_CARRIER_ carrier;

    if(!pinfo || !pcarrier)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_CARRIER_;
    ptlv->len=htons(len);

    carrier.carrierID=htonl(pcarrier->carrierID);
    carrier.type=pcarrier->type;
    carrier.bw=htonl(pcarrier->bw);
    carrier.centerFreq=htonl(pcarrier->centerFreq);
    carrier.power=htons(pcarrier->power);
    carrier.modulation=pcarrier->modulation;
    carrier.fec=pcarrier->fec;
    carrier.fecRate=pcarrier->fecRate;
    carrier.alpha=pcarrier->alpha;
    
    memcpy((ptlv+1),&carrier,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_add_result_tlv(char *pinfo,
        struct _STR_RESULT_ *presult,int len)
{
    struct tlv_hdr *ptlv;

    if(!pinfo || !presult)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_RESULT_;
    ptlv->len=htons(len);

    memcpy((ptlv+1),presult,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_add_devId_tlv(char *pinfo,
        struct _STR_DEV_ID_ *pdevId,int len)
{
    struct tlv_hdr *ptlv;
    struct _STR_DEV_ID_ devId;
    
    if(!pinfo || !pdevId)
        return 0;
    
    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_DEV_ID_;
    ptlv->len=htons(len);
    
    devId.devId=htonl(pdevId->devId);
    devId.devType=htonl(pdevId->devType);
    
    memcpy((ptlv+1),&devId,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_router_tlv(char *pinfo,struct _STR_ADD_ROUTER_ *prouter,int len,char oper)
{    
    struct _STR_ADD_ROUTER_ router;
    
    if(!pinfo || !prouter)
        return 0;
    
    struct tlv_hdr *ptlv=(struct tlv_hdr *)pinfo;
    if(oper & CFG_FLAG_ADD)
        ptlv->type = _ADD_ROUTER_;
    else if(oper & CFG_FLAG_DEL)
        ptlv->type = _DEL_ROUTER_;
    else
        return 0;

    ptlv->len = htonl(len);
    router.dstip=htonl(prouter->dstip);
    router.masklen=prouter->masklen;
    router.gateway=htonl(prouter->gateway);
    memcpy(router.ifname,prouter->ifname,20);
    router.metric=htons(prouter->metric);
    
    memcpy((ptlv+1),&router,len);
    
    return (len+TLV_HEAD_LEN);
}


int packet_add_modem_tlv(char *pinfo,
        struct _STR_MODEM_ *pmodem,int len)
{
    struct tlv_hdr *ptlv;
    struct _STR_MODEM_ modem;
        
    if(!pinfo || !pmodem)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_MODEM_;
    ptlv->len=htons(len);

    modem.typecode=htons(pmodem->typecode);
    modem.ip=htonl(pmodem->ip);
    modem.satIp=htonl(pmodem->satIp);
    modem.devId=htonl(pmodem->devId);
    memcpy(modem.devSN,pmodem->devSN,9);
    
    memcpy((ptlv+1),&modem,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_add_gwip_tlv(char *pinfo,
        struct _STR_DEFAULT_GWIP_ *pgwip,int len)
{
    struct tlv_hdr *ptlv;
    struct _STR_DEFAULT_GWIP_ gwip;
    
    if(!pinfo || !pgwip)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_DEFAULT_GWIP_;
    ptlv->len=htons(len);
    
    gwip.gateway=htonl(pgwip->gateway);
    memcpy((ptlv+1),&gwip,len);
    
    return (len+TLV_HEAD_LEN);   
}

/*Add vlan TLV to packet*/
int packet_add_vlan_tlv(char *pinfo,
    struct _STR_VLAN_ *pvlan,int len)
{
    struct tlv_hdr *ptlv;
    
    if(!pinfo || !pvlan)
        return 0;
    
    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type=_VLAN_;
    ptlv->len=htons(len);

    struct _STR_VLAN_ *ptr;
    ptr=(struct _STR_VLAN_ *)(ptlv+1);
    ptr->cnt=htons(pvlan->cnt);
    memcpy(ptr->vlan,pvlan->vlan,len-sizeof(short));
    
    return (len + TLV_HEAD_LEN);
}

int packet_add_chacomm_tlv(char *pinfo,struct _STR_CHANNEL_COMM_ *pchacomm,int len)
{    
    struct tlv_hdr *ptlv;
    struct _STR_CHANNEL_COMM_ chacomm;
    
    if(!pinfo || !pchacomm)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type = _CHANNEL_COMM_;
    ptlv->len = htons(len);
    
    chacomm.type=pchacomm->type;
    chacomm.fliterBW=pchacomm->fliterBW;
    chacomm.filterMode=pchacomm->filterMode;
    chacomm.cf_freq=htonl(pchacomm->cf_freq);

    memcpy(pinfo,&chacomm,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_add_cha_tlv(char *pinfo,struct _STR_CHANNEL_ *pcha,int len)
{    
    struct tlv_hdr *ptlv;
    struct _STR_CHANNEL_ cha;

    if(!pinfo || !pcha)
        return 0;

    ptlv=(struct tlv_hdr *)pinfo;
    ptlv->type = _CHANNEL_;
    ptlv->len = htons(len);

    cha.id=pcha->id;
    cha.type=pcha->type;
    cha.freq=htonl(pcha->freq);
    cha.bw=htonl(pcha->bw);
    cha.power=htons(pcha->power);
    cha.sweepRange=htonl(pcha->sweepRange);
    cha.modulation=pcha->modulation;
    cha.fec=pcha->fec;
    cha.fecRate=pcha->fecRate;
    cha.ncr=pcha->ncr;
    cha.freqRvs=pcha->freqRvs;
    cha.rollingFactor=pcha->rollingFactor;
    cha.txChaId=htonl(pcha->txChaId);
    
    memcpy(pinfo,&cha,len);
    
    return (len+TLV_HEAD_LEN);
}

int packet_qosrule_tlv(char *pinfo,
    struct _STR_ADD_QOSRULE_ITEMS_ *pqosrule,int len,char flag)
{
    short *ptr;
    struct tlv_hdr *ptlv;
    
    if(!pinfo || !pqosrule)
        return -1;
    
    ptlv=(struct tlv_hdr *)pinfo;
    
    if((CFG_FLAG_ADD & flag) || (CFG_FLAG_UPDATE & flag))
    {
        if(CFG_FLAG_ADD & flag)
            ptlv->type = _ADD_QOSRULE_ITEMS_;
        else
            ptlv->type = _UPDATE_QOSRULE_ITEMS_;
        memcpy((ptlv+1),pqosrule->rule,len);
    }
    else if(CFG_FLAG_DEL & flag)
    {
        ptlv->type = _DEL_QOSRULE_ITEMS_;        
        ptr=(short *)(ptlv+1);
        short *id=(short *)(pqosrule->rule);
        *ptr = *id;  
    }
    
    ptlv->len = htons(len);
    
    return (len+TLV_HEAD_LEN);
}

int ncs2dev_send_routers_all(struct ncs_object *ncs,struct dev_obj *dev)
{
    int size,cnt;
    int typelen,len=0;
    char *packet,*pinfo;

    if(NULL==(packet=(char *)malloc(PACKET_PDU_MAX)))
        return -1;
    else
        memset(packet,0,PACKET_PDU_MAX);
    
    struct _STR_ADD_ROUTER_ *pnode,*p_routers=NULL;
    cnt=get_cfg_dev_routers_by_devId(dev->devId,&p_routers,NULL);
    if(cnt == 0 || !p_routers)
        goto STOP_SEND;
    else
    {             
        pnode=p_routers;
        pinfo=packet;
        
        size=sizeof(struct _STR_ADD_ROUTER_);
        
        for(int i=0;i < cnt; i++)
        {
            if((len+TLV_HEAD_LEN+size) >= PACKET_PDU_MAX)
            {
                ncs2dev_send_cfg(ncs,dev,pinfo,len); 
                pinfo=packet;
                memset(pinfo,0,PACKET_PDU_MAX);
            }
            
            typelen = packet_router_tlv(pinfo,pnode,size,CFG_FLAG_ADD);
            len += typelen;
            pinfo += typelen;
            pnode++;
        }
        
        if(len != 0)
            ncs2dev_send_cfg(ncs,dev,pinfo,len);
    }            
    
STOP_SEND:
    if(p_routers)
        free(p_routers);
    
    free(packet);
    
    return -1;
}

/*ncs send all qosrule configures to dev when the pp 
begin to logon successfully*/
int ncs2dev_send_qosrules_all(struct ncs_object *ncs,struct dev_obj *dev)
{
    int cnt,typelen,len=0;
    char *packet,*pinfo;

    if(NULL==(packet=(char *)malloc(PACKET_PDU_MAX)))
        return -1;
    memset(packet,0,PACKET_PDU_MAX);
    
    struct qosrule_items *pnode,*p_qosrule=NULL;
    cnt=get_cfg_dev_qosrules_by_devId(dev->devId,&p_qosrule,NULL);
    if(cnt == 0 || !p_qosrule)
        goto STOP_SEND;
    else
    {             
        pnode=p_qosrule;
        pinfo=packet;
        
        for(int i=0;i<cnt;i++)
        {
            if((len+TLV_HEAD_LEN+pnode->len) >= PACKET_PDU_MAX)
            {
                ncs2dev_send_cfg(ncs,dev,pinfo,len); 
                pinfo=packet;
                memset(pinfo,0,PACKET_PDU_MAX);
            }
            
            typelen = packet_qosrule_tlv(pinfo,&(pnode->items),pnode->len,CFG_FLAG_UPDATE);
            len += typelen;
            pinfo += typelen;
            pnode++;
        }
        
        if(len != 0)
            ncs2dev_send_cfg(ncs,dev,pinfo,len);
    }            
    
STOP_SEND:
    if(p_qosrule)
        free(p_qosrule);
    
    free(packet);
    
    return -1;
}

int ncs2rx_openrxpath_req(struct ncs_object *ncs,struct dev_obj *rx,
    struct _STR_CHANNEL_ID_ *prxchaId)
{
    int ret,len;
    int bytes=0;
    char *pbuff;
    struct packet_hdr *packet;
    struct _STR_CHANNEL_ rxcha;
    struct _STR_CHANNEL_COMM_ chacomm;
    
    if(!ncs || !rx || !prxchaId)
        return -1;

    if(!(packet=build_packet(PACKET_PDU_MAX)))
        return -1;
    
    packet->srcType=DEV_TYPE_NCS;
    packet->srcDevId=htonl(ncs->devId);
    packet->seq=htonl(get_seq(&(rx->s_seq)));
    packet->msg=htons(__NCS2RX_OPENRXCHA_REQ__);

    /*add chaId information to packet*/
    pbuff=(char *)(packet+1);
    len=sizeof(struct _STR_CHANNEL_ID_);
    bytes+=packet_add_chaId_tlv((pbuff+bytes),prxchaId,len);

    /*add cha information to packet*/
    len=0;
    if(-1!=get_cfg_dev_cha_by_devId_chaId(
        prxchaId->devId,prxchaId->chaId,&rxcha,&len))
        bytes+=packet_add_cha_tlv((pbuff+bytes),&rxcha,len);

    /*add cha_comm information to packet*/
    len=0;
    //if(!rx_if_used(rx))
    if(-1 != get_cfg_dev_channel_comm_by_devId_flag(prxchaId->devId, &chacomm,&len, CFG_FLAG_ID))
        bytes+=packet_add_chacomm_tlv((pbuff+bytes), &chacomm,len);
    
    packet->len=htonl(bytes);
    ret=ncs_send_packet(ncs->servd_fd,rx->ip,rx->port,(char *)packet,(bytes+PACKET_HEAD_LEN));
    if(0 == ret){
        struct packet_ctl *packetctl;
        packetctl=ncs_add_packetctl_list(rx,(char *)packet,(bytes+PACKET_HEAD_LEN));
        add_retransmit_timer(ncs,packetctl);
        rx_rxpath_used_add(rx,1);
    }
    else
        ncs_log(ERR,"%s ncs send open rxpath failure",__func__);
    
    return ret;   
}

/*ncs send vlan configure to pp*/
int ncs2pp_send_vlan(struct ncs_object *ncs,struct dev_obj *pp)
{
    int len=0;
    char *packet,*pinfo;

    if(NULL== ncs || NULL==pp)
        return -1;

    packet=(char *)malloc(PACKET_PDU_MAX);
    if(NULL==packet)
        return -1;
    
    struct _STR_VLAN_ vlancfg;       
    if(-1 == get_cfg_dev_vlan(ncs->devId,&vlancfg,&len))
        goto END;
    else
    {
        pinfo = packet;
        len = packet_add_vlan_tlv(pinfo,&vlancfg,len);
        if(0 != len)
            ncs2dev_send_cfg(ncs,pp,pinfo,len);
    }
      
END:
    free(packet);
    return 0;
}

int ncs2pp_send_pars(struct ncs_object *ncs,
    struct dev_obj *pp)
{
    int ret,bytes=0,len=0;
    char *packet,*pinfo;
    
    if(!(packet=(char *)malloc(PACKET_PDU_MAX)))
        return -1;
    
    pinfo=packet;
    memset(packet,0,PACKET_PDU_MAX);
    
    /*To do: Add ipaddr to packet*/

    /*Add SIG-EMS's Txchannel to packet*/
    struct dev_obj *sig;
    struct _STR_CHANNEL_ txcha;
    sig=ncs_get_active_sig(ncs);
    if(NULL != sig)
    {
        ret = get_cfg_dev_cha_by_devId_chaId(sig->devId,PATH_FIRST,&txcha,&len);
        if(-1 != ret)
        {
            len=packet_add_cha_tlv(pinfo,&txcha,len);
            pinfo += len;
            bytes += len;
        }
    }
    
    /*To do: Add work_mode to packet*/
    len=0;
    struct _STR_WORK_MODE_ workmode;
    ret=get_cfg_dev_workmode_by_devId_flag(sig->devId,&workmode,&len,CFG_FLAG_ID);
    if(-1 != ret)
    {
        len=packet_add_workmode_tlv(pinfo, &workmode, len);
        pinfo += len;
        bytes += len;
    }
    
    /*To do: Add multicast to packet*/

    ncs2dev_send_cfg(ncs,pp, pinfo, bytes);
    
    free(packet);
    return 0;
}

/* ncs send all configures to pp when the pp begin
to logon successfully */
int ncs2pp_send_allcfg(struct ncs_object *ncs,
    struct dev_obj *pp)
{
    if(!ncs || !pp)
        return -1;

    ncs2pp_send_pars(ncs,pp);
    ncs2pp_send_vlan(ncs,pp);
    ncs2dev_send_routers_all(ncs,pp);
    ncs2dev_send_qosrules_all(ncs,pp);
    
    return 0;
}

int ncs2sig_send_allcfg(struct ncs_object *ncs,struct dev_obj *sig)
{   
    if(!ncs || !sig)
        return -1;

    return ncs2dev_send_cfg_01(ncs,sig);
}

int ncs2dev_logon_ack(struct ncs_object *ncs,struct dev_obj *dev,char val)
{ 
    int len;
    struct packet_hdr*packet;    
    struct _STR_RESULT_ res;
  
    if(!ncs || !dev)
        return -1;

    len=TLV_HEAD_LEN+sizeof(res);
    if(packet=build_packet(len)) 
    {        
        ncs_log(ERR,"%s Build packet failure",__func__);
        return -1;
    }

    if(dev->type == DEV_TYPE_PP)
        packet->msg = htons(__NCS2PP_LOGON_ACK__);
    else if(dev->type == DEV_TYPE_SIGEMS)
        packet->msg = htons(__NCS2SIG_LOGON_ACK__);
    else if(dev->type == DEV_TYPE_RXEMS)
        packet->msg = htons(__NCS2RX_LOGON_ACK__);
    else if(dev->type == DEV_TYPE_RCST)
        packet->msg = htons(__NCS2RCST_LOGON_ACK__);
    else
       packet->msg = htons(0); 
    packet->seq = htonl(get_seq(&(dev->r_seq)));   
    packet->srcType = DEV_TYPE_NCS;   
    packet->srcDevId = htonl(ncs->devId);
    
    /*Build TLV message*/    
    res.result = val;
    packet_add_result_tlv((char *)(packet+1),&res,sizeof(res));

    if(0 != ncs_send_packet(ncs->servd_fd,dev->ip,dev->port,(char *)packet,len))
    {
        ncs_log(ERR,"%s ncs send dev(Id:%d) logon ack failure",__func__,dev->devId);
        return -1;
    }
    
    return 0;
}

int ncs2pp_logon_ack(struct ncs_object *ncs,struct dev_obj *pp,char val)
{
    return ncs2dev_logon_ack(ncs,pp,val);
}

/*ncs receive pp's logon request message*/
int logon_pp2ncs_req(struct ncs_object *ncs,
    struct dev_obj *dev,void *arg,int len)
{
    struct tlv_hdr *ptlv;
    char *pmsg=(char *)arg;
    FSM_CALLFUNC func;
    
    if(!ncs || !dev || !arg)
        return -1;
    
    if(len <= 0)
        return -1;
    /*get tlv message point*/
    ptlv = (struct tlv_hdr *)pmsg;
    /*check the length of packet message*/
    if(len != (TLV_HEAD_LEN + sizeof(struct _STR_IPPORT_))
        || ntohs(ptlv->len) != sizeof(struct _STR_IPPORT_))
    {
        ncs_log(ERR,"the pp logon request packet's len is wrong");
        goto LOGON_FAILURE;
    }
    /*check the pp's ip address*/
    struct _STR_IPPORT_ *pipport;
    pipport=(struct _STR_IPPORT_ *)(ptlv+1);
    if(ntohl(pipport->ip) == dev->ip)
    {
        ncs2pp_logon_ack(ncs,dev,SUCCESS);
        
        if(func = PP_FSM[dev->state][PP_AUTH_SUCCESS].func)
            func(ncs,dev,NULL,0); 
        pp_fsm_change(dev,PP_AUTH_SUCCESS);
        
        return 0;
    }
    
LOGON_FAILURE:    
    ncs2pp_logon_ack(ncs,dev,FAILURE);
    
    return -1;
}

int dev_proc_parcfg_update_ack(struct ncs_object *ncs,
    struct dev_obj *dev,char *buf,int len)
{
    char result;
    struct tlv_hdr *ptlv;
    struct packet_ctl *packet;

    ptlv=(struct tlv_hdr *)buf;
    if(len != sizeof(struct _STR_RESULT_))
        result=1;
    else if(_RESULT_ == ptlv->type)
        result=*(char *)(ptlv+1);
    else
        result=1;

    if(1==result)
        ncs_log(WARN,"receive sigems parameters error");

    if(packet=find_packetctl(dev->out,dev->r_seq))
    {
        if(event_del(packet->retry_timerev))
            ncs_log(ERR,"delete timer event failure");
            
        del_packetctl(dev->out, packet);
    }

    return 0;
}


int dev_proc_report_msg(struct ncs_object *ncs,
    struct dev_obj *dev,char *buf,int len)
{
    int msglen;
    struct _STR_DEV_ID_ *pdevId;
    
    if(!ncs || !dev || !buf)
        return -1;
    
    msglen=len+sizeof(struct _STR_DEV_ID_);
    pdevId=(struct _STR_DEV_ID_ *)malloc(msglen);
    if(NULL==pdevId)
        return -1;
    else
        memset(pdevId,0,msglen);

    pdevId->devType=dev->type;
    pdevId->devId=htonl(dev->devId);
    memcpy((pdevId+1),buf,len); 
    
    ncs2nms_send_report_msg(ncs->client_fd, (void *)pdevId, msglen);
    free(pdevId);
    return 0;
}

int dev_proc_poll_ack(struct ncs_object *ncs,
    struct dev_obj *dev,char *buf,int len)
{
    char type;
    short tlvlen;
    char *pmsg;
    int i=len;
    struct tlv_hdr *ptlv;
    struct _STR_DEV_STATUS_ *pstatus=NULL;
    struct _STR_EQUIPMENT_FAULT_ *pfault=NULL;
    struct _STR_LICENSE_INFO_ *plicinfo=NULL;
    
    dev->pollTries=0;
 
    if(len == 0)
        return 0;
        
    if(pmsg=(char *)malloc(PACKET_PDU_MAX))
        memset(pmsg,0,PACKET_PDU_MAX);
    else
        return 0; 

    int bytes=0;
    struct _STR_DEV_ID_ devId;
    devId.devType=DEV_TYPE_SIGEMS;        
    devId.devId=dev->devId;  
    bytes += packet_add_devId_tlv((pmsg+bytes),&devId,sizeof(devId));
    ptlv=(struct tlv_hdr *)buf;
    while(i > 0)
    {
        type=ptlv->type;
        tlvlen=ntohs(ptlv->len);
        
        if(i < (tlvlen+TLV_HEAD_LEN))
            return -1;

        if(type==_DEV_STATUS_)
        {
            pstatus=(struct _STR_DEV_STATUS_ *)(ptlv+1); 
            memcpy((pmsg+bytes),pstatus,sizeof(struct _STR_DEV_STATUS_));
            bytes+=sizeof(struct _STR_DEV_STATUS_);
        }
        else if(type==_LICENSE_INFO_)
        {
            plicinfo=(struct _STR_LICENSE_INFO_ *)(ptlv+1);
            memcpy((pmsg+bytes),plicinfo,sizeof(struct _STR_EQUIPMENT_FAULT_));
            bytes+=sizeof(struct _STR_EQUIPMENT_FAULT_);
        }
        else if(type==_EQUIPMENT_FAULT_)
        {
            pfault=(struct _STR_EQUIPMENT_FAULT_ *)(ptlv+1);
            memcpy((pmsg+bytes),pfault,sizeof(struct _STR_LICENSE_INFO_));
            bytes+=sizeof(struct _STR_LICENSE_INFO_);
        }
        else
            ncs_log(ERR,"%s the unknow tlv type",__func__);
        
        i -= (tlvlen+TLV_HEAD_LEN);
        ptlv = (struct tlv_hdr *)((char *)(ptlv+1)+tlvlen);
    }

    ncs2nms_send_report_msg(ncs->client_fd, pmsg, bytes);
            
    /*To do: process the equipment fault*/
    if(pfault->fault)
    {
        ncs_proc_modem_fault(ncs,dev,pfault->fault); 
        ncs_log(ERR,"%s the dev(type:%d Id:%d) occurs fault",
            __func__,dev->type,dev->devId);
    }
    
    if(pmsg)
        free(pmsg);
    
    return 0;  
}

void ncs_proc_rcst_fault(struct ncs_object *ncs,
    struct dev_obj *rcst)
{
    int ret,event;
    FSM_CALLFUNC func;

    ncs_log(WARN,"%s this rcst(Id:%d) occur fault",__func__,rcst->devId);

    event=RECEIVE_RCST_FAULT;
    if(func=RCST_FSM[rcst->state][event].func)
        if(-1 != (ret=func(ncs,rcst,NULL,0)))
            rcst_fsm_change(rcst,event);
        
    return;
}

void ncs_proc_rx_fault(struct ncs_object *ncs,
    struct dev_obj *rx)
{
    int i,event,num;
    struct dev_obj *newrx,*rcst;
    FSM_CALLFUNC func;
    struct _STR_CHANNEL_ID_ rxchaId;
    struct _STR_CHANNEL_ID_ txchaId;
    struct rcst_rx rcstrx[PATH_FOURTH];
    
    if(!ncs || !rx)
        return;

    if(ncs_rx_switch(rx->devId,rcstrx,&num))
    {
        ncs_log(INFO,"%s rxswitch realloc resource success",__func__);
        
        for(int i=0;i<num;i++)
        {
            if((rcst=ncs_find_rcst(ncs,rcstrx[i].txchaId.devId))
                && (newrx=ncs_find_rx(ncs,rcstrx[i].rxchaId.devId)))
            {                
                int bytes;
                char *pmsg;
                struct _STR_DEFAULT_GWIP_ gwip;
                if(pmsg=(char *)malloc(PACKET_PDU_MAX))
                    memset(pmsg,0,PACKET_PDU_MAX);
                else{
                    ncs_log(ERR,"%s malloc memory failure",__func__);
                    goto SWITCH_ERR;
                }

                gwip.gateway=newrx->ip;
                bytes=packet_add_gwip_tlv(pmsg,&gwip,sizeof(gwip));
                ncs2dev_send_cfg(ncs,rcst,pmsg,bytes);
                free(pmsg);

                ncs2rx_openrxpath_req(ncs,newrx,&(rcstrx[i].rxchaId));
            }
            else
            {
SWITCH_ERR:
                ncs_log(ERR,"%s rcst(Id:%d) or rx(Id:%d) switch error",
                    __func__,rcstrx[i].txchaId.devId,rcstrx[i].rxchaId.devId);
                
                event=RECEIVE_NMS_RELRCSTRES_REQ;
                if(func=RCST_FSM[rcst->state][event].func)
                    if(-1!=func(ncs,rcst,&txchaId,sizeof(txchaId)))
                        rcst_fsm_change(rcst,event);
            }
        }
    }
    else
    {
        ncs_log(WARN,"%s rxswitch realloc resource failure",__func__);
        
        rxchaId.devId=rx->devId;
        for(int i=PATH_FIRST;i<=PATH_FOURTH;i++)
        {
            rxchaId.chaId=i;
            if(ncs_getrcst_by_rx(&rxchaId,&txchaId)
                && (rcst=ncs_find_rcst(ncs, txchaId.devId)))
            {
                event=RECEIVE_NMS_RELRCSTRES_REQ;
                if(func=RCST_FSM[rcst->state][event].func)
                    if(-1 != func(ncs,rcst,&txchaId,sizeof(txchaId)))
                        rcst_fsm_change(rcst,event);
            }
        }
    }
    
    rxchaId.chaId=0XFF;
    ncs2rx_closerxpath_req(ncs,rx, &rxchaId);

    return;
}

int ncs_sig_switch(int devId,int *newdevId)
{
    if(!newdevId)
        return FALSE;
    
    if(ncs_sigSwith_byBreakdown(devId,newdevId))
        return TRUE;
    else
        return FALSE;
}

void ncs_proc_sig_fault(struct ncs_object *ncs,
    struct dev_obj *sig)
{
    int newdevId;
    struct dev_obj *newsig;
    
    if(!ncs || !sig)
        return;

    if(ncs_sig_switch(sig->devId,&newdevId))
    {
        ncs_log(INFO,"%s ncs get new sig(Id:%d) success",
            __func__,newdevId);
        
        UNSET_BIT(sig->flag,DEV_FLAG_ACTIVE);
        if(newsig=ncs_find_sig(ncs,newdevId))
            SET_BIT(sig->flag,DEV_FLAG_ACTIVE);
    }

    return;
}

void ncs_proc_modem_fault(struct ncs_object *ncs,
    struct dev_obj *dev,char fault)
{
    if(!ncs || !dev)
        return;

    if(fault==TRUE)
    {
        if(dev->type==DEV_TYPE_RCST)
            ncs_proc_rcst_fault(ncs,dev);
        else if(dev->type==DEV_TYPE_RXEMS)
            ncs_proc_rx_fault(ncs,dev);
        else if(dev->type==DEV_TYPE_SIGEMS)
            ncs_proc_sig_fault(ncs,dev);
        else
        {
            ncs_log(ERR,"%s the unknow dev type(%s)",
                __func__,dev->type);
            return;
        }
    }
    else
        ncs_log(INFO,"%s the dev(type:%d Id:%d) fault is resolved",
            __func__,dev->type,dev->devId);
    
    set_cfg_dev_equipfualt_by_devId(dev->devId,fault);
     
    return;
}

int ncs_polldev_offline(struct ncs_object *ncs,
    struct dev_obj *dev,char devType)
{
    FSM_CALLFUNC func;
    
    if(DEV_TYPE_PP == devType)
    {
        func=PP_FSM[dev->state][POLL_PP_OFFLINE].func;
        if(func)
            func(ncs,dev,NULL,0);
        pp_fsm_change(dev,POLL_PP_OFFLINE);
    }
    else if(DEV_TYPE_SIGEMS == devType)
    {
        func=SIG_FSM[dev->state][POLL_SIGEMS_OFFLINE].func;
        if(func)
            func(ncs,dev,NULL,0);
        pp_fsm_change(dev,POLL_SIGEMS_OFFLINE);
    }
    else if(DEV_TYPE_RXEMS == devType)
    {
        func=RX_FSM[dev->state][POLL_RXEMS_OFFLINE].func;
        if(func)
            func(ncs,dev,NULL,0);
        pp_fsm_change(dev,POLL_RXEMS_OFFLINE);
    }
    else
        ncs_log(ERR,"%s the devType(%s ) is not include",
                    __func__,devType);
   
    return 0;
}



/*This function is that NCS polling devs including 
PP,SIGEMS,RXEMS,but not including RCST. If ncs want
poll the rcst,please use ncs_poll_rcst()*/
int ncs_poll_dev(struct ncs_object *ncs,
        struct dev_obj *dev,int devType)
{
    struct packet_hdr *poll_info;
    int ret=0;
    
    if(!ncs || !dev)
        return -1;
    
    if(ONLINE != dev->state || 
        (DEV_TYPE_PP != devType && 
        DEV_TYPE_SIGEMS != devType && 
        DEV_TYPE_RXEMS != devType))
        return -1;
    
    if(dev->pollTries < ncs->g_retransmit_max) 
    {
        /*Building the polling dev packet head*/
        if(NULL == (poll_info=build_packet(0)))  
            return -1;

        if(devType == DEV_TYPE_PP)
            poll_info->msg = htons(__NCS2PP_POLL_REQ__);
        else if(devType == DEV_TYPE_SIGEMS)
            poll_info->msg = htons(__NCS2SIG_POLL_REQ__);
        else
            poll_info->msg = htons(__NCS2RX_POLL_REQ__);

        /*Init the polling packet head*/                          
        poll_info->srcType = DEV_TYPE_NCS;
        poll_info->srcDevId = htons(ncs->devId);
        poll_info->seq = htonl(get_seq(&(dev->s_seq))); 

        if(ret=ncs_send_packet(ncs->servd_fd,dev->ip,dev->port,
                                           (char *)poll_info,PACKET_HEAD_LEN))
        {
            ncs_log(ERR,"%s Ncs send polling packet to dev(%d:%d) failure",
                    __func__,dev->ip,dev->port);
        }
        else
            dev->pollTries++;

        /*free the polling packet memory*/
        free(poll_info);
    }
    else
    {
        dev->pollTries = 0;
        dev->pollSeq = 0;
        
        ncs_polldev_offline(ncs,dev,devType); 
        ncs_log(WARN,"%s dev(%d) is polling offline",__func__,dev->devId);
    }
    
    return ret;   
}

void ncs_poll_rx(int fd,short event,void *arg)
{
    struct listnode  *node; 
    struct dev_obj *rxems;
    struct dev_set *rxset;
    struct ncs_object *ncs=arg;

    int online_cnt;

    if(!ncs)
        return;
    
    rxset=ncs->rx_set;
    online_cnt=rxset->count;
    if(!online_cnt)
        goto DEL_TIMER;

    /*Traverse the RXEMS Dev Set, if the RXEMS is on line 
    send polling packet to RXEMS and set timer*/
    LIST_LOOP(rxset->dev_list,rxems,node)
    {
        if(ONLINE != rxems->state)
            continue;

        online_cnt--;

        if(0 != ncs_poll_dev(ncs,rxems,DEV_TYPE_RXEMS))
            ncs_log(ERR,"%s NCS polls rxems(%d) failure",
                        __func__,rxems->devId);
           
        if(!online_cnt)
            break;
    }

    /*Del timer event for polling rxems if the rxset's count == 0*/
DEL_TIMER:
    if(!online_cnt && rxset->poll_timerev){
        event_del(rxset->poll_timerev);
        rxset->poll_timerev=NULL;
    }

    return;
}

void ncs_poll_sig(int fd,short event,void *arg)
{
    struct dev_obj *sig;
    struct dev_set *sigSet;
    struct ncs_object *ncs=arg;
    struct listnode  *node; 

    if(!ncs)
        return;
    
    sigSet=ncs->pp_set;
    if(!sigSet->count)
        goto DEL_TIMER;

    LIST_LOOP(sigSet->dev_list,sig,node)
    {
        if(ONLINE == sig->state)
            if(0 != ncs_poll_dev(ncs,sig,DEV_TYPE_SIGEMS))
                ncs_log(ERR,"%s NCS polls pp(%d) failure",__func__,sig->devId);
    }
    
DEL_TIMER:
    if(!sigSet->count && sigSet->poll_timerev){
        event_del(sigSet->poll_timerev);
        sigSet->poll_timerev=NULL;
    }

    return;
}

void ncs_poll_pp(int fd,short event,void *arg)
{
    struct dev_obj *pp;
    struct dev_set *ppSet;
    struct ncs_object *ncs=arg;
    
    if(!ncs)
        return;
    
    ppSet=ncs->pp_set;
    if(!ppSet->count)
        goto DEL_TIMER;

    if(pp=listnode_head(ppSet->dev_list))
    {
        if(ONLINE != pp->state)
            goto DEL_TIMER;
        
        ncs_poll_dev(ncs,pp,DEV_TYPE_PP);
    }     
    
DEL_TIMER:
    if(!ppSet->count && ppSet->poll_timerev){
        event_del(ppSet->poll_timerev);
        ppSet->poll_timerev=NULL;
    }

    return;  
}

void ncs_poll_rcst(int fd,short event,void *arg)
{
    int groupNum,ip,
         online_cnt,
         groupCnt=0;
    struct dev_obj *rcst,*sig;
    struct dev_set *rcstSet;
    struct ncs_object *ncs=arg;
    struct packet_hdr *pollhdr;
    struct listnode  *node; 
    struct tlv_hdr *ptlv;
    char *packet;
    short port=DEF_POLL_RCST_PORT;

    if(!ncs || !(rcstSet=ncs->rcst_set))
        return;
    
    if(!(online_cnt=rcstSet->count))
        goto END_POLL;
    
    /*Get the ncs polling rcst groupNum*/
    if(0 != get_polling_maxNum(&groupNum))
        groupNum=DEF_POLLING_GROUPNUM;

    /*Build rcst polling packet memory*/
    int len=groupNum*(TLV_HEAD_LEN +
                sizeof(struct _STR_DEV_ID_));
    if(NULL==(packet=(char *)build_packet(len)))
    {
        ncs_log(ERR,"%s memory alloc failure",__func__);
        return;
    }
    
    /*Init the polling packet head*/
    pollhdr=(struct packet_hdr *)packet;
    pollhdr->srcType=DEV_TYPE_NCS;
    pollhdr->srcDevId=htonl(ncs->devId);
    pollhdr->msg=htons(__NCS2RCST_POLL_REQ__);
    
    /* when polling rcst,ncs uses the SIGEMS's ip,port and seq */
    if(sig=ncs_get_active_sig(ncs))
        pollhdr->seq=htonl(get_seq(&(sig->s_seq)));
    else
    {
        ncs_log(ERR,"%s Ncs do not have this SIGEMS",__func__);
        free(packet);
        return;
    }
    
    ptlv=(struct tlv_hdr *)(pollhdr+1);

    /*Traverse the rcst dev list,find the online devs and poll them.
    if the pollTries of rcst < g_retransmit_max,then poll them;else
    we think it logoff,process the logoff event*/
    LIST_LOOP(rcstSet->dev_list,rcst,node)
    {  /*To do: the lock state need to poll ???*/
        if(RCST_ONLINE != rcst->state 
            && RCST_ONLINE_OPENRX != rcst->state 
            && RCST_ACTIVE != rcst->state 
            && RCST_ONLINE_RELRES != rcst->state)
            return;

        online_cnt--;

        if(rcst->pollTries < ncs->g_retransmit_max)
        {          
            struct _STR_DEV_ID_ str_dev_id={DEV_TYPE_RCST,htonl(rcst->devId)};

            ptlv=(struct tlv_hdr *)build_tlv(ptlv,_DEV_ID_,
                &str_dev_id,sizeof(struct _STR_DEV_ID_));
            
            groupCnt++;
            rcst->pollTries++;
        }
        else if(rcst->pollTries >= ncs->g_retransmit_max)
        {
            rcst->pollTries=0;
            
            FSM_CALLFUNC func;
            if(func=RCST_FSM[rcst->state][POLL_RCST_OFFLINE].func)
                if(-1!=func(ncs,rcst,NULL,0))
                    rcst_fsm_change(rcst,POLL_RCST_OFFLINE);
                
            ncs_log(WARN,"%s dev(%d) is poll offline",__func__,rcst->devId);
        }
        
        if(groupCnt >= groupNum || !online_cnt)
        {
            int bytes = PACKET_HEAD_LEN + groupCnt*
                (TLV_HEAD_LEN+sizeof(struct _STR_DEV_ID_));
            
            pollhdr->len=htonl(bytes-PACKET_HEAD_LEN);

            /*If ncs sends polling packet failure, should subtract the 
            rcst's pollTries,and wait for the next polling time*/
            if(ncs_send_packet(ncs->servd_fd,sig->ip,port,(char *)packet,bytes))
            {
                ptlv =(struct tlv_hdr *)(pollhdr+1);
                for(int i=1;i<groupCnt;i++)
                {   
                    struct _STR_DEV_ID_ *pdevId = (struct _STR_DEV_ID_ *)(ptlv+1);                    
                    if(rcst=ncs_find_rcst(ncs, pdevId->devId))
                        rcst->pollTries--;
                    ptlv = (struct tlv_hdr *)(pdevId+1);
                }
                ncs_log(ERR,"%s Ncs send polling packets failure", __func__);
            }
            
            /*There don't have online state devs in the dev-list*/
            if(!online_cnt)
                goto END_POLL;
             
            /*After this rcst group send polling packet ,
            then ncs need send next group polling packet*/
            groupCnt = 0;
            pollhdr->seq = htonl(get_seq(&(sig->s_seq)));
            ptlv=(struct tlv_hdr *)(pollhdr+1);
            memset(ptlv,0,len);
        }      
    }

END_POLL:
    if(!online_cnt && rcstSet->poll_timerev){
        event_del(rcstSet->poll_timerev);
        rcstSet->poll_timerev=NULL;
    }
    
    free(packet);
    return;
}

int rcst_proc_poll_ack(struct ncs_object *ncs,
    struct dev_obj *rcst,char *buf,int len)
{
    if(!ncs || !rcst || !buf)
        return -1;

    return dev_proc_poll_ack(ncs,rcst,buf,len);
}

int ncs2dev_send_cfg_01(struct ncs_object *ncs,struct dev_obj *dev)
{
    int bytes=0;
    int size=0;
    char *pbuff;

    if(NULL==(pbuff=(char *)malloc(PACKET_PDU_MAX)))
        return -1;
    else
        memset(pbuff,0,PACKET_PDU_MAX);

    /*get dev information from database*/
    NCS_MODEM_INFO  siginfo;
    if(get_cfg_dev_info_by_devId(dev->devId,&siginfo) > 0)
    {
        /*add dev name to packet*/     
        if(strlen(siginfo.Name))
        {
            struct _STR_DEV_NAME_ devname;
            memcpy(devname.name,siginfo.Name,strlen(siginfo.Name));
            bytes += packet_add_devname_tlv((pbuff+bytes),&devname,strlen(siginfo.Name));
        }
        /*add default gateway to packet*/         
        struct _STR_DEFAULT_GWIP_ gwip;
        gwip.gateway=ncs->servd_ip;
        bytes += packet_add_gwip_tlv((pbuff+bytes),&gwip,sizeof(gwip));
    }
    
    /*add dev time to packet*/
    struct _STR_DEV_TIME_ devtime;
    devtime.time=time((time_t *)NULL);
    bytes += packet_add_devtime_tlv((pbuff+bytes),&devtime,sizeof(devtime));

    /*add channel comm information to packet*/
    struct _STR_CHANNEL_COMM_ chacomm;
    if(-1 != get_cfg_dev_channel_comm_by_devId_flag(dev->devId,&chacomm, &size, CFG_FLAG_ID))
        bytes += packet_add_chacomm_tlv((pbuff+bytes), &chacomm, size);
    
    /*add channel information to packet*/
    size=0;
    struct _STR_CHANNEL_ cha;
    if(-1 != get_cfg_dev_cha_by_devId_chaId(dev->devId,PATH_FIRST,&cha,&size))
        bytes += packet_add_cha_tlv((pbuff+bytes), &cha, size);

    /*add vlan information to packet*/
    size=0;
    struct _STR_VLAN_ vlaninfo;
    if(-1!=get_cfg_dev_vlan(ncs->devId,&vlaninfo,&size))
        bytes += packet_add_vlan_tlv((pbuff+bytes), &vlaninfo,size);
    
    ncs2dev_send_cfg(ncs, dev, pbuff,bytes);

    free(pbuff);
    return 0;
}


int ncs2dev_send_cfg_02(struct ncs_object *ncs,struct dev_obj *dev)
{
    int bytes=0;
    int size=0;
    char *pbuff;

    if(pbuff=(char *)malloc(PACKET_PDU_MAX))
        memset(pbuff,0,PACKET_PDU_MAX);
    else
        return -1;

    /*add workmode information to packet*/
    struct _STR_WORK_MODE_ workmode;
    if(-1 != get_cfg_dev_workmode_by_devId_flag(
        dev->devId, &workmode, &size, CFG_FLAG_ID))
        bytes+=packet_add_workmode_tlv((pbuff+bytes),&workmode,size);

    /*add resource-bod information to packet*/
    size=0;
    struct _STR_RESOURCE_BOD_ resourcebod;
    if(-1 != get_cfg_dev_resource_bod_by_devId_flag(
        dev->devId, &resourcebod, &size, CFG_FLAG_ID))
        bytes+=packet_add_resourcebod_tlv((pbuff+bytes),&resourcebod,size);

    /*add resource-rule information to packet*/
    size=0;
    struct _STR_RESOURCE_RULE_ITEMS_ resourcerule;
    if(-1 != get_cfg_dev_resource_rule_by_devId_flag(
        dev->devId, &resourcerule, &size, CFG_FLAG_ID))
        bytes+=packet_add_resourcerule_tlv((pbuff+bytes),&resourcerule,size);
    
    ncs2dev_send_cfg(ncs, dev, pbuff,bytes);

    free(pbuff);
    return 0;
}

int logon_modem2ncs_req(struct ncs_object *ncs,
    struct dev_obj *dev,struct tlv_hdr *ptlv,int len)
{
    int i=len;
    char type;
    short bytes;
    struct _STR_MODEM_ modem;
    struct _STR_LICENSE_INFO_ license;

    while(i > 0)
    {
        type=ptlv->type;
        bytes=ntohs(ptlv->len);

        if(i < (bytes + TLV_HEAD_LEN))
            return FAILURE;

        if(type == _LICENSE_INFO_)
            memcpy(&license,(ptlv+1),bytes);
        else if(type == _MODEM_)
            memcpy(&modem,(ptlv+1),bytes);
        else
            ncs_log(ERR,"%s the unknow tlv type",__func__);

        ptlv = (struct tlv_hdr *)((char *)(ptlv+1)+bytes);
        i -= (bytes+TLV_HEAD_LEN);
    }

    return modem_auth_check(dev,&modem,&license);
    
}

int ncs2rcst_lockreltxpath_req(struct ncs_object *ncs,
    struct dev_obj *rcst,struct _STR_CHANNEL_ID_ *ptxchaId)
{
    int len,ret;
    int bytes=0;
    char *pbuff;
    struct packet_hdr *packet;

    if(!ncs || !rcst || !ptxchaId)
        return -1;
    
    packet=build_packet(PACKET_PDU_MAX);
    packet->srcType=DEV_TYPE_NCS;
    packet->srcDevId=htonl(ncs->devId);
    packet->seq=htonl(get_seq(&(rcst->s_seq)));
    packet->msg=htons(__NCS2RCST_CARRIERLOCK_RELEASE_REQ__);

    pbuff=(char *)(packet+1);
    len=sizeof(struct _STR_CHANNEL_ID_);
    bytes+=packet_add_chaId_tlv((pbuff+bytes), ptxchaId,len);
    
    packet->len=htonl(bytes);
    ret=ncs_send_packet(ncs->servd_fd, rcst->ip, rcst->port,
        (char *)packet,(bytes+PACKET_HEAD_LEN));
    if(0 == ret){
        struct packet_ctl *packetctl;
        packetctl=ncs_add_packetctl_list(rcst,(char *)packet,(bytes+PACKET_HEAD_LEN));
        add_retransmit_timer(ncs,packetctl);
    }
    
    free(packet);
    return 0;
}

int ncs2rcst_relres_ack(struct ncs_object *ncs,
    struct dev_obj *rcst,char val)
{
    int bytes;
    char *pbuff;
    struct packet_hdr *packet;
    struct _STR_RESULT_ result;
    
    if(!ncs || !rcst)
        return -1;

    if(!(packet=build_packet(PACKET_PDU_MAX)))
        return -1;
    
    packet->srcType=DEV_TYPE_NCS;
    packet->srcDevId=htonl(ncs->devId);
    packet->seq=htonl(get_seq(&(rcst->r_seq)));
    packet->msg=htons(__NCS2RCST_RESOURCE_ACK__);

    pbuff=(char *)(packet+1);
    result.result=val;
    bytes+=packet_add_result_tlv((pbuff+bytes),&result, sizeof(result));

    packet->len=htonl(bytes);
    if(-1==ncs_send_packet(ncs->servd_fd,rcst->ip,rcst->port,(char *)packet,(bytes+PACKET_HEAD_LEN)))
        ncs_log(ERR,"%s ncs send resource release ack failure",__func__);

    return 0;
}

int ncs2rcst_logoff_ack(struct ncs_object *ncs,struct dev_obj *rcst,char val)
{
    int bytes;
    char *pbuff;
    struct packet_hdr *packet;
    struct _STR_RESULT_ result;
    
    if(!ncs || !rcst)
        return -1;

    if(!(packet=build_packet(PACKET_PDU_MAX)))
        return -1;
    
    packet->srcType=DEV_TYPE_NCS;
    packet->srcDevId=htonl(ncs->devId);
    packet->seq=htonl(get_seq(&(rcst->r_seq)));
    packet->msg=htons(__NCS2RCST_LOGOFF_ACK__);

    pbuff=(char *)(packet+1);
    result.result=val;
    bytes+=packet_add_result_tlv((pbuff+bytes),&result, sizeof(result));

    packet->len=htonl(bytes);
    if(-1==ncs_send_packet(ncs->servd_fd,rcst->ip,rcst->port,(char *)packet,(bytes+PACKET_HEAD_LEN)))
        ncs_log(ERR,"%s ncs send logoff ack failure",__func__);

    return 0;
}

int ncs2rcst_resalloc_ack(struct ncs_object *ncs,
    struct dev_obj *rcst,char val)
{
    int ret,bytes;
    char *pbuff;
    struct packet_hdr *packet;
    struct _STR_RESULT_ result;
    
    if(!ncs || !rcst)
        return -1;

    if(!(packet=build_packet(PACKET_PDU_MAX)))
        return -1;
    
    packet->srcType=DEV_TYPE_NCS;
    packet->srcDevId=htonl(ncs->devId);
    packet->seq=htonl(get_seq(&(rcst->r_seq)));
    
    if(CHECK_BIT(rcst->flag,DEV_FLAG_BOD))
    {
        packet->msg=htons(__NCS2RCST_BOD_ACK__);
        UNSET_BIT(rcst->flag,DEV_FLAG_BOD);
    }
    else if(CHECK_BIT(rcst->flag,DEV_FLAG_BODREL))
    {
        packet->msg=htons(__NCS2RCST_BOD_RELEASE_ACK__);
        UNSET_BIT(rcst->flag,DEV_FLAG_BODREL);
    }
    else
        packet->msg=htons(__NCS2RCST_RESOURCE_ACK__);

    pbuff=(char *)(packet+1);
    if(val==TRUE)
    {
        struct _STR_DEFAULT_GWIP_ gwip;
        struct _STR_RESOURCE_  resource;
        struct _STR_CHANNEL_ID_ txchaId;
        struct _STR_CHANNEL_ID_ rxchaId;
        
        txchaId.devId=rcst->devId;
        txchaId.chaId=PATH_FIRST;
        if(ncs_getres_by_rcst(&txchaId, &rxchaId,&resource))
        {
            struct dev_obj *rx;
            if(rx=ncs_find_rx(ncs,rxchaId.devId)){
                struct _STR_DEFAULT_GWIP_ gwip;
                gwip.gateway=rx->ip;
                bytes+=packet_add_gwip_tlv((pbuff+bytes),&gwip,sizeof(gwip));
            }

            bytes+=packet_add_resource_tlv((pbuff+bytes),&resource,sizeof(resource));
        }
    }

    /*add result to packet*/
    result.result=val;
    bytes+=packet_add_result_tlv((pbuff+bytes),&result,sizeof(result));
    packet->len=htonl(bytes);

    ret=ncs_send_packet(ncs->servd_fd, rcst->ip,rcst->port,(char *)packet,(bytes+PACKET_HEAD_LEN));
    if(-1==ret)
        ncs_log(ERR,"%s ncs send resource alloc ack packet failure",__func__);
    
    return ret;
}

int ncs2rcst_logoff_req(struct ncs_object *ncs,struct dev_obj *rcst,
    struct _STR_CHANNEL_ID_ *ptxchaId)
{
    int ret,len;
    int bytes=0;
    char *pbuff;
    struct packet_hdr *packet;
    
    if(!ncs || !rcst || !ptxchaId)
        return -1;
    
    packet=build_packet(PACKET_PDU_MAX);
    packet->srcType=DEV_TYPE_NCS;
    packet->srcDevId=htonl(ncs->devId);
    packet->seq=htonl(get_seq(&(rcst->s_seq)));
    packet->msg=htons(__NCS2RCST_LOGOFF_REQ__);
    
    pbuff=(char *)(packet+1);
    len=sizeof(struct _STR_CHANNEL_ID_);
    bytes+=packet_add_chaId_tlv((pbuff+bytes),ptxchaId,len);
    packet->len=htonl(bytes);
    
    ret=ncs_send_packet(ncs->servd_fd,rcst->ip,rcst->port,(char *)packet,(bytes+PACKET_HEAD_LEN));
    if(0 == ret){
        struct packet_ctl *packetctl;
        packetctl=ncs_add_packetctl_list(rcst,(char *)packet,(bytes+PACKET_HEAD_LEN));
        add_retransmit_timer(ncs,packetctl);
    }
    else
        ncs_log(ERR,"%s ncs send to rcst(Id:%d) logoff req failure",
            __func__,rcst->devId);
    
    return ret;   
}

int ncs2rcst_send_allcfg(struct ncs_object *ncs,struct dev_obj *rcst)
{
    if(!ncs || !rcst)
        return -1;

    ncs2dev_send_cfg_01(ncs, rcst);
    ncs2dev_send_cfg_02(ncs, rcst);
    ncs2dev_send_qosrules_all(ncs, rcst);

    return 0;
}

int ncs2rcst_relres_req(struct ncs_object *ncs,struct dev_obj *rcst,
    struct _STR_CHANNEL_ID_ *ptxchaId)
{
    int len,ret;
    int bytes=0;
    char *pbuff;
    struct packet_hdr *packet;

    if(!ncs || !rcst || !ptxchaId)
        return -1;
    
    packet=build_packet(PACKET_PDU_MAX);
    packet->srcType=DEV_TYPE_NCS;
    packet->srcDevId=htonl(ncs->devId);
    packet->seq=htonl(get_seq(&(rcst->s_seq)));
    packet->msg=htons(__NCS2RCST_RELEASE_RESOURCE_REQ__);

    pbuff=(char *)(packet+1);
    bytes+=packet_add_chaId_tlv((pbuff+bytes), ptxchaId,len);
    
    packet->len=htonl(bytes);
    ret=ncs_send_packet(ncs->servd_fd, rcst->ip, rcst->port,(char *)packet,(bytes+PACKET_HEAD_LEN)); 
    if(0 == ret)
    {
        struct packet_ctl *packetctl;
        packetctl=ncs_add_packetctl_list(rcst,(char *)packet,(bytes+PACKET_HEAD_LEN));
        add_retransmit_timer(ncs,packetctl);
    }
    else
        ncs_log(ERR,"%s ncs send rcst(Id:%d) release resource failure",__func__,rcst->devId);
    
    free(packet);
    return ret;
}

int ncs2rcst_logon_ack(struct ncs_object *ncs,struct dev_obj *rcst,char val)
{
    return ncs2dev_logon_ack(ncs,rcst,val); 
}

int ncs2rcst_locktxpath_req(struct ncs_object *ncs,struct dev_obj *rcst,
    struct _STR_CHANNEL_ID_ *ptxchaId,struct _STR_RESOURCE_ *presource)
{
    int len,ret;
    int bytes=0;
    char *pbuff;
    struct packet_hdr *packet;
    
    packet=build_packet(PACKET_PDU_MAX);
    packet->srcType=DEV_TYPE_NCS;
    packet->srcDevId=htonl(ncs->devId);
    packet->seq=htonl(get_seq(&(rcst->s_seq)));
    packet->msg=htons(__NCS2RCST_CARRIERLOCK_CHA_REQ__);

    pbuff=(char *)(packet+1);
    bytes+=packet_add_chaId_tlv((pbuff+bytes), ptxchaId,len);
    
    if(0 != presource->freq && 0 != presource->BW)
        bytes+=packet_add_resource_tlv((pbuff+bytes),presource, sizeof(struct _STR_RESOURCE_));
    
    packet->len=htonl(bytes);
    ret=ncs_send_packet(ncs->servd_fd, rcst->ip, rcst->port,
        (char *)packet,(bytes+PACKET_HEAD_LEN));
    
    if(0 == ret)
    {
        struct packet_ctl *packetctl;
        packetctl=ncs_add_packetctl_list(rcst,(char *)packet,(bytes+PACKET_HEAD_LEN));
        add_retransmit_timer(ncs,packetctl);
    }
    
    free(packet);
    return 0;
}

int rcst_proc_parcfg_update_ack(struct ncs_object *ncs,
    struct dev_obj *rcst,char *buf,int len)
{
      if(!ncs || !rcst || !buf)
        return -1;

    return dev_proc_parcfg_update_ack(ncs,rcst,buf,len);
}

int rcst_proc_report_msg(struct ncs_object *ncs,
    struct dev_obj *rcst,char *buf,int len)
{
    if(!ncs || !rcst || !buf)
        return -1; 
    
    return dev_proc_report_msg(ncs,rcst,buf,len);
}

int rcst_sigproc(struct ncs_object *ncs,
    struct packet_hdr *phdr,char *buf,int ip,short port)
{
    int ret;
    short msg,event;
    struct dev_obj *rcst;
    FSM_CALLFUNC func;
    
    if(!ncs || !phdr || !buf)
        return -1;

    if(!(rcst=ncs_find_rcst(ncs,phdr->srcDevId)))
        return -1;
    
    /*check the dev's ip addr*/
    if(ip != rcst->ip)
    {
        ncs_log(WARN,"%s this rx's ip addr(%d) is wrong",__func__,ip);
        return -1;
    }
    else
    {
        rcst->port=port;
        
        if(rcst->r_seq == phdr->seq)
            rcst->try_flag=TRUE;
        else{
            rcst->try_flag=FALSE;
            rcst->r_seq=phdr->seq;
        }
    }
    
    msg = phdr->msg;
    if(__RCST2NCS_POLL_ACK__ == msg)
    {
        rcst_proc_poll_ack(ncs,rcst,buf,phdr->len);
        return 0;
    }
    else if(__RCST2NCS_PARCFG_UPDATE_ACK__ == msg)
    {
        rcst_proc_parcfg_update_ack(ncs,rcst,buf,phdr->len);
        return 0;
    }
    else if(__RCST2NCS_REPORT__ == msg
              || __RX2NCS_CFGRESULT_REPORT_REQ__ == msg)
    {
        rcst_proc_report_msg(ncs,rcst,buf,phdr->len);
        return 0;
    }
    else if(__RCST2NCS_LOGON_REQ__ == msg)
        event=RECEIVE_RCST_LOGON_REQ;
    else if(__RCST2NCS_LOGOFF_REQ__ == msg)
        event=RECEIVE_RCST_LOGOFF_REQ;
    else if(__RCST2NCS_LOGOFF_ACK__ == msg)
        event=RECEIVE_RCST_LOGOFF_ACK;
    else if(__RCST2NCS_RESOURCE_REQ__ == msg)
        event=RECEIVE_RCST_RES_REQ;
    else if(__RCST2NCS_RELEASE_RESOURCE_REQ__ == msg)
        event=RECEIVE_RCST_RELRES_REQ;
    else if(__RCST2NCS_RELEASE_RESOURCE_ACK__ == msg)
        event=RECEIVE_RCST_RELRES_ACK;
    else if(__RCST2NCS_BOD_REQ__ == msg)
        event=RECEIVE_RCST_BOD_REQ;
    else if(__RCST2NCS_BOD_RELEASE_REQ__ == msg)
        event=RECEIVE_RCST_BODREL_REQ;
    else
        event=RXEMS_FSM_EVENT_MAX;
    
   if(func=RCST_FSM[rcst->state][event].func)
        ret=func(ncs,rcst,buf,phdr->len);

   if(-1 != ret)
        rcst_fsm_change(rcst,event);
        
    return 0;
}


int ncs_rx_switch(int rxdevId,struct rcst_rx *prcst_rx,int *pnum)
{
    char ret;
    int num;
    infoForSwitch newrx[PATH_FOURTH];

    if(!prcst_rx || !pnum)
        return FALSE;
    
    ret=ncs_rxSwith_byBreakdown(rxdevId,newrx,&num);
    if(ret && num)
    {
        *pnum=num;
        for(int i=0;i<num;i++)
        {
            prcst_rx[i].rxchaId.devId=newrx[i].newRxDevIDInfo.devID;
            prcst_rx[i].rxchaId.chaId=newrx[i].newRxDevIDInfo.chanId;
            prcst_rx[i].txchaId.devId=newrx[i].rcstID;
            prcst_rx[i].txchaId.chaId=PATH_FIRST;
        }
    }

    return ret;
}


int ncs2rx_closerxpath_req(struct ncs_object *ncs,struct dev_obj *rx,
    struct _STR_CHANNEL_ID_ *prxchaId)
{
    int ret,len;
    int bytes=0;
    char *pbuff;
    struct packet_hdr *packet;

    if(!(packet=build_packet(PACKET_PDU_MAX)))
        return -1;
    packet->srcType=DEV_TYPE_NCS;
    packet->srcDevId=htonl(ncs->devId);
    packet->seq=htonl(get_seq(&(rx->s_seq)));
    packet->msg=htons(__NCS2RX_CLOSERXCHA_REQ__);
    
    pbuff=(char *)(packet+1);
    len=sizeof(struct _STR_CHANNEL_ID_);
    bytes+=packet_add_chaId_tlv((pbuff+bytes),prxchaId, len);
    packet->len=htonl(bytes);
    
    ret=ncs_send_packet(ncs->servd_fd,rx->ip,rx->port,(char *)packet,(bytes+PACKET_HEAD_LEN));
    if(0 == ret)
    {
        struct packet_ctl *packetctl;
        packetctl=ncs_add_packetctl_list(rx,(char *)packet,(bytes+PACKET_HEAD_LEN));
        add_retransmit_timer(ncs,packetctl);
        
        if(prxchaId->chaId==0XFF)
            rx_rxpath_used_dec(rx,4);
        else
            rx_rxpath_used_dec(rx,1);
    }
    else
        ncs_log(ERR,"%s ncs send close rxpath failure",__func__);
    
    return ret;   
}

int ncs2rx_logon_ack(struct ncs_object *ncs,struct dev_obj *rx,char val)
{
    return ncs2dev_logon_ack(ncs,rx,val);
}

int ncs2rx_send_allcfg(struct ncs_object *ncs,struct dev_obj *rx)
{
    if(!ncs || !rx)
        return -1;

    return ncs2dev_send_cfg_01(ncs, rx);
}


int rx_proc_report_msg(struct ncs_object *ncs,
    struct dev_obj *rx,char *buf,int len)
{
    if(!ncs || !rx || !buf)
        return -1; 
    
    return dev_proc_report_msg(ncs,rx,buf,len);
}

int rx_proc_parcfg_update_ack(struct ncs_object *ncs,
    struct dev_obj *rx,char *buf,int len)
{
    if(!ncs || !rx || !buf)
        return -1;

    return dev_proc_parcfg_update_ack(ncs,rx,buf,len);
}


int rx_proc_poll_ack(struct ncs_object *ncs,
    struct dev_obj *rx,char *buf,int len)
{
        if(!ncs || !rx || !buf)
        return -1;

    return dev_proc_poll_ack(ncs,rx,buf,len);
}

int rx_sigproc(struct ncs_object *ncs,
    struct packet_hdr *phdr,char *buf,int ip,short port)
{
    short msg,event;
    struct dev_obj *rx;
    FSM_CALLFUNC func;
    
    if(!ncs || !phdr || !buf)
        return -1;

    if(!(rx=ncs_find_rx(ncs,phdr->srcDevId)))
        return -1;
    
    /*check the dev's ip addr*/
    if(ip != rx->ip)
    {
        ncs_log(WARN,"%s this rx's ip addr(%d) is wrong",__func__,ip);
        return -1;
    }
    else
    {
        rx->port=port;
        
        if(rx->r_seq == phdr->seq)
            rx->try_flag=TRUE;
        else{
            rx->try_flag=FALSE;
            rx->r_seq=phdr->seq;
        }
    }
    
    msg = phdr->msg;
    if(__RX2NCS_POLL_ACK__ == msg)
    {
        rx_proc_poll_ack(ncs,rx,buf,phdr->len);
        return 0;
    }
    else if(__RX2NCS_PARCFG_UPDATE_ACK__ == msg)
    {
        rx_proc_parcfg_update_ack(ncs,rx,buf,phdr->len);
        return 0;
    }
    else if(__RX2NCS_REPORT__ == msg
              || __RX2NCS_CFGRESULT_REPORT_REQ__ == msg)
    {
        rx_proc_report_msg(ncs,rx,buf,phdr->len);
        return 0;
    }
    else if(__RX2NCS_LOGON_REQ__ == msg)
        event=RECEIVE_RXEMS_LOGON_REQ;
    else if(__RX2NCS_OPENRXCHA_ACK__ == msg)
        event=RECEIVE_RXEMS_OPENRXPATH_ACK;
    else if(__RX2NCS_CLOSERXCHA_ACK__ == msg)
        event=RECEIVE_RX_CLOSERXPATH_ACK;
    else
        event=RXEMS_FSM_EVENT_MAX;
    
   if(func=RX_FSM[rx->state][event].func)
        func(ncs,rx,buf,phdr->len);
   
    rx_fsm_change(rx,event);
        
    return 0;
}


int ncs2sig_logon_ack(struct ncs_object *ncs,struct dev_obj *sig,char val)
{
    return ncs2dev_logon_ack(ncs,sig,SUCCESS);
}

int sig_proc_poll_ack(struct ncs_object *ncs,
    struct dev_obj *sig,char *buf,int len)
{
    if(!ncs || !sig || !buf)
        return -1;

    return dev_proc_poll_ack(ncs,sig,buf,len);
}

/*receive the packet ack of paramaters or configures*/
int sig_proc_parcfg_update_ack(struct ncs_object *ncs,
    struct dev_obj *sig,char *buf,int len)
{    
    if(!ncs || !sig || !buf)
        return -1;

    return dev_proc_parcfg_update_ack(ncs,sig,buf,len);
}

int sig_proc_report_msg(struct ncs_object *ncs,
    struct dev_obj *sig,char *buf,int len)
{
    int msglen;
    struct _STR_DEV_ID_ *pdevId;
    
    return dev_proc_report_msg(ncs,sig,buf,len);
}

int sig_sigproc(struct ncs_object *ncs,
    struct packet_hdr *phdr,char *buf,int ip,short port)
{
    int ret;
    short msg,event;
    struct dev_obj *sig;
    FSM_CALLFUNC func;
    
    if(!ncs || !phdr || !buf)
        return -1;

    if(!(sig=ncs_find_sig(ncs,phdr->srcDevId)))
        return -1;
    
    /*check the dev's ip addr*/
    if(ip != sig->ip)
    {
        ncs_log(WARN,"%s this sig's ip addr(%d) is wrong",__func__,ip);
        return -1;
    }
    else
    {
        sig->port=port;
        
        if(sig->r_seq == phdr->seq)
            sig->try_flag=TRUE;
        else{
            sig->try_flag=FALSE;
            sig->r_seq=phdr->seq;
        }
    }
    
    msg = phdr->msg;
    if(__SIG2NCS_POLL_ACK__ == msg)
    {
        sig_proc_poll_ack(ncs,sig,buf,phdr->len);
        return 0;
    }
    else if(__SIG2NCS_PARCFG_UPDATE_ACK__ == msg)
    {
        sig_proc_parcfg_update_ack(ncs,sig,buf,phdr->len);
        return 0;
    }
    else if(__SIG2NCS_REPORT__ == msg
              || __SIG2NCS_CFGRESULT_REPORT_REQ__ == msg)
    {
        sig_proc_report_msg(ncs,sig,buf,phdr->len);
        return 0;
    }
    else if(__SIG2NCS_LOGON_REQ__ == msg)
        event=RECEIVE_SIGEMS_LOGON_REQ;
    else if(__SIG2SIG_OPENCHA_ACK__ == msg)
        event=RECEIVE_RXEMS_OPENRXPATH_ACK;
    else
        event=RSIGEMS_FSM_EVENT_MAX;
    
   if(func=SIG_FSM[sig->state][event].func)
        ret=func(ncs,sig,buf,phdr->len);
   
   if(-1 != ret)
        sig_fsm_change(sig,event);
        
    return 0;
}

int pp_proc_poll_ack(struct ncs_object *ncs,
    struct dev_obj *pp,char *buf,int len)
{
    if(!ncs || !pp)
        return -1;

    ncs_log(INFO,"Ncs recv pp's polling ack");

    if(0 != len)
        ncs_log(ERR,"The pp's polling ack packet is wrong");
    
    /* Set the pollTries 0 */
    pp->pollTries = 0;

    return 0;
}


int pp_proc_parcfg_update_ack(struct ncs_object *ncs,
    struct dev_obj *pp,char *buf,int len)
{
    char result;
    struct tlv_hdr *ptlv;
    struct packet_ctl *packetctl;

    if(!ncs || !pp || !buf)
        return -1;

    ptlv=(struct tlv_hdr *)buf;

    if(len != sizeof(struct _STR_RESULT_))
    {
        result = 1;
        ncs_log(ERR,"The packet's len is wrong");
    }
    else if(_RESULT_ == ptlv->type)
        result=*(char *)(ptlv+1);
    else
    {
        result=1;
        ncs_log(WARN,"The TLV type is not request");
    } 

    if(packetctl=find_packetctl(pp->out, pp->r_seq))
    {
        if(event_del(packetctl->retry_timerev))
            ncs_log(ERR,"delete timer event failure");            
        del_packetctl(pp->out, packetctl);
    }
    else
        ncs_log(ERR,"ncs not find the ack's request packet");
    
    return 0;
}

int pp_proc_report_msg(struct ncs_object *ncs,
    struct dev_obj *pp,char *buf,int len)
{    
    int msglen;
    struct _STR_DEV_ID_ *pdevId;
    
    return dev_proc_report_msg(ncs,pp,buf,len);
}

int pp_sigproc(struct ncs_object *ncs,
    struct packet_hdr *phdr,char *buf,int ip,short port)
{
    short msg,event;
    struct dev_obj *pp;
    FSM_CALLFUNC proc;
    
    if(!ncs || !phdr || !buf)
        return -1;

    if(!(pp=ncs_find_pp(ncs,phdr->srcDevId)))
        return -1;
    
    /*Check the dev's IP addr*/
    if(ip != pp->ip)
    {
        ncs_log(WARN,"%s this pp's IP addr(%d) is wrong",
                        __func__,ip);
        return -1;
    }
    else
    {
        pp->port=port;
        if(pp->r_seq == phdr->seq)
            pp->try_flag=TRUE;
        else{
            pp->try_flag=FALSE;
            pp->r_seq=phdr->seq;
        }
    }
    
    msg = phdr->msg;

    if(__PP2NCS_POLL_ACK__ == msg)
    {
        pp_proc_poll_ack(ncs,pp,buf,phdr->len);
        return 0;
    }
    else if(__PP2NCS_PARCFG_UPDATE_ACK__ == msg)
    {
        pp_proc_parcfg_update_ack(ncs,pp,buf,phdr->len);
        return 0;
    }
    else if(__PP2NCS_REPORT__ == msg
              || __PP2NCS_CFGRESULT_REPORT_REQ__ == msg)
    {
        pp_proc_report_msg(ncs,pp,buf,phdr->len);
        return 0;
    }
    else if(__PP2NCS_LOGON_REQ__ == msg)
        event=RECEIVE_PP_LOGON_REQ;
    else
        event=PP_FSM_EVENT_NULL;
    
   if(proc=PP_FSM[pp->state][event].func)
        proc(ncs,pp,buf,phdr->len);
   
    pp_fsm_change(pp,event);
        
    return 0;
}

int ncs_add_sigserv(struct ncs_object *ncs)
{
    if(!ncs)
        return -1;
    
    if((ncs->servd_fd = ncs_udp_serv_open(ncs->servd_port)) < 0)
    {
        ncs_log(ERR,"%s Create ncs unix server error",__func__);
        return -1;
    }
     
    evutil_make_socket_nonblocking(ncs->servd_fd);
    ncs->ncs_serv_recvev=event_new(ncs->g_base,
                    ncs->servd_fd,(EV_READ |EV_PERSIST),
                    ncs->ncs_serv_recv,(void*)ncs);

    if(!ncs->ncs_serv_recvev)
    {
        ncs_log(ERR,"Create new ncs_serv_recvev event error");
        return -1;
    }

    return 0;
}

void ncs_sigserv_recv(int fd,short event,void *arg)
{
    int bytes;
    char buff[BUFF_MAX];
    char *pinfo;
    int addrlen;
    struct packet_hdr *phdr;
    struct ncs_object *ncs=arg;
    struct sockaddr_in addr;
    
    if(!arg || !(event & EV_READ))
        return;
    
    addrlen=sizeof(struct sockaddr_in);
    bytes=recvfrom(fd,&buff,BUFF_MAX,0,
                            (struct sockaddr*)&addr,
                            &addrlen);
    if(bytes < 0)
    {
        ncs_log(ERR,"%s read packet error %s",__func__,strerror(errno));
        return;
    }
    else if(0==bytes)
    {
        ncs_log(WARN,"%s read 0 byte packet",__func__);
        return;
    }

    ncs_log(INFO,"receive packet %d bytes",bytes);
    
    /*get dev's IP-addr and port*/
    int ip=ntohl(addr.sin_addr.s_addr);
    short port=ntohs(addr.sin_port);

    phdr=(struct packet_hdr *)buff;
    phdr->msg = ntohs(phdr->msg);
    phdr->seq = ntohl(phdr->seq);
    phdr->srcDevId = ntohl(phdr->srcDevId);
    phdr->len = ntohs(phdr->len);

    if(phdr->len != (bytes-PACKET_HEAD_LEN))
    {
         ncs_log(ERR,"%s the packet len(%d) != recv bytes(%d)",
                    __func__,phdr->len,(bytes-PACKET_HEAD_LEN));
        return;
    }
    
    /*Version check and Len check*/
    if(NCS_VERSION != phdr->ver 
        || phdr->len < 0 
        || phdr->len > (BUFF_MAX-TLV_HEAD_LEN))
    {
        ncs_log(ERR,"%s The packet(ver:%d len:%d) is not right",
                        __func__,phdr->ver,phdr->len);
        return;
    }

    ncs_log(INFO,"%s ncs receive packet from %d:%d",__func__,ip,port);

    pinfo=buff+PACKET_HEAD_LEN;

    switch(phdr->srcType)
    {
        case DEV_TYPE_PP:
            pp_sigproc(ncs,phdr,pinfo,ip,port);
            break;
        case DEV_TYPE_SIGEMS:
            sig_sigproc(ncs,phdr,pinfo,ip,port);
            break;
        case DEV_TYPE_RXEMS:
            rx_sigproc(ncs,phdr,pinfo,ip,port);
            break;
        case DEV_TYPE_RCST:
            rcst_sigproc(ncs,phdr,pinfo,ip,port);
            break;
        default:
            ncs_log(ERR,"%s the dev type(%d) is unknow",
                        __func__,phdr->srcType);
    }

    return; 
}

int ncs_creat_serv(struct ncs_object *ncs)
{
    if(!ncs || (ONLINE != ncs->state))
        return -1;

    ncs->servd_fd=ncs_udp_serv_open(ncs->servd_port);
    if(ncs->servd_fd < 0)
    {
        ncs_log(ERR,"%s open ncs servd failure,%s",
                    __func__,strerror(errno));
        return -1;
    }
    evutil_make_socket_nonblocking(ncs->servd_fd);
    /*Add receive server packet event*/
    ncs->ncs_serv_recvev=event_new(ncs->g_base,
                            ncs->servd_fd,(EV_READ|EV_PERSIST),
                            ncs->ncs_serv_recv,ncs);
    event_add(ncs->ncs_serv_recvev,NULL);

    return 0;       
}



